#include "Drip_rate.h"
#include "stdio.h"
#include "string.h"

// 全局变量定义
unsigned char Drip_Mode = 0;           // 水滴的状态 0：管内无水  1：管内有水
unsigned char Drip_Mode_Last = 0;      // 水滴上一次的状态  0：管内无水  1：管内有水
unsigned long int Drip_Num = 0;        // 水滴的总个数
unsigned long int Drip_Window_Num = 0; // 时间窗口内的水滴个数
float Dosage;               //药水的总量


extern volatile uint32_t uwtick;       // 系统总计时
uint32_t Time_Last_Drip = 0;           // 上一滴的时间戳
uint32_t Time_Window_Start = 0;        // 测量窗口开始时间
uint32_t Time_Between_Drops = 0;       // 两滴之间的时间间隔
uint32_t Last_Time_Intervals[5] = {0}; // 存储最近5次滴落的时间间隔

#define DRIP_WINDOW_TIME 10000   // 滴速计算窗口时间(ms)
#define DRIP_NO_DROP_ALARM 8000  // 无滴报警时间(ms)

//// 滴速状态定义
//#define DRIP_STATUS_NORMAL 0     // 正常滴速
//#define DRIP_STATUS_TOO_FAST 1   // 滴速过快
//#define DRIP_STATUS_TOO_SLOW 2   // 滴速过慢
//#define DRIP_STATUS_NO_DROP 3    // 无滴落

unsigned char Drip_Status = DRIP_STATUS_NORMAL; // 滴速状态
unsigned char Drip_Velocity = 0;                // 水滴的滴速(滴/分钟)
unsigned int Instant_Drip_Velocity = 0;        // 即时滴速(滴/分钟)

/**
 * @brief 初始化滴速检测
 */
void Drip_rate_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    // 使能GPIO时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

    // 配置传感器输入引脚
    GPIO_InitStructure.GPIO_Pin = Drop_PORT_Pin;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;   // 下拉输入
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(Drop_PORT, &GPIO_InitStructure);
    
    // 初始化变量
//    Drip_Num = 0;
    Drip_Window_Num = 0;
    Time_Last_Drip = uwtick;
    Time_Window_Start = uwtick;
    Drip_Status = DRIP_STATUS_NORMAL;

}

/**
 * @brief 计算平均滴速(基于时间窗口)
 */
void Drip_Rate_Calculation(void)
{
    uint32_t current_time = uwtick;
    uint32_t window_time = current_time - Time_Window_Start;
    
    // 当窗口时间达到设定值时计算滴速
    if (window_time >= DRIP_WINDOW_TIME) {
        // 计算滴速(滴/分钟)
        if (Drip_Window_Num > 0) {
            Drip_Velocity = (unsigned int)((float)Drip_Window_Num * 60000.0f / (float)window_time);
            
            // 更新滴速状态
            if (Drip_Velocity < DRIP_RATE_MIN) {
                Drip_Status = DRIP_STATUS_TOO_SLOW;
            } else if (Drip_Velocity > DRIP_RATE_MAX) {
                Drip_Status = DRIP_STATUS_TOO_FAST;
            } else {
                Drip_Status = DRIP_STATUS_NORMAL;
            }
        } else {
            // 窗口内无滴落
            Drip_Velocity = 0;
            Drip_Status = DRIP_STATUS_NO_DROP;
        }
        
        // 打印滴速信息
        printf("滴速: %d 滴/分钟，状态: %d\r\n", Drip_Velocity, Drip_Status);
        
        // 重置窗口计数
        Drip_Window_Num = 0;
        Time_Window_Start = current_time;
    }
    
    // 检查是否长时间无滴落
    if (current_time - Time_Last_Drip > DRIP_NO_DROP_ALARM) {
        Drip_Status = DRIP_STATUS_NO_DROP;
        printf("警告：长时间无滴落(%d秒)\r\n", (current_time - Time_Last_Drip) / 1000);
    }
}

/**
 * @brief 计算即时滴速(基于最近两滴时间间隔)
 */
void Calculate_Instant_Rate(void)
{
    // 确保有有效的时间间隔
    if (Time_Between_Drops > 0) {
        // 计算即时滴速(滴/分钟)
        Instant_Drip_Velocity = (unsigned char)(60000.0f / (float)Time_Between_Drops);
        
        // 更新历史时间间隔数组(用于未来的平滑处理)
        for (int i = 4; i > 0; i--) {
            Last_Time_Intervals[i] = Last_Time_Intervals[i-1];
        }
        Last_Time_Intervals[0] = Time_Between_Drops;
        
        printf("即时滴速: %d 滴/分钟\r\n", Instant_Drip_Velocity);
//        LCD_ShowIntNum(0, 30, Instant_Drip_Velocity, 3, BLUE, WHITE, 32);
    }
        LCD_ShowIntNum(0, 30, 72, 3, RED, WHITE, 32);
}

/**
 * @brief 滴速处理函数
 */
void Drip_rate_task(void)
{
    uint32_t current_time = uwtick;
    
    // 读取传感器状态
    Drip_Mode = GPIO_ReadInputDataBit(Drop_PORT, Drop_PORT_Pin);
    
    // 检测滴落(由1变为0表示滴落)
    if (Drip_Mode == 0 && Drip_Mode_Last == 1) {
        // 计算两滴之间的时间间隔
        Time_Between_Drops = current_time - Time_Last_Drip;
        
//        // 计算即时滴速
//        Calculate_Instant_Rate();
        
        // 更新记录
        Drip_Num++;
        Drip_Window_Num++;
//        Dosage_Count();
        Time_Last_Drip = current_time;
//        send_sensor_data();
    }
    // 计算即时滴速
    Calculate_Instant_Rate();
    // 更新上一次状态
    Drip_Mode_Last = Drip_Mode;
    
    // 计算滴速
    Drip_Rate_Calculation();
}

/**
 * @brief 获取当前滴速
 * @return 滴速(滴/分钟)
 */
unsigned char Get_Drip_Velocity(void)
{
    return Drip_Velocity;
}

/**
 * @brief 获取即时滴速
 * @return 即时滴速(滴/分钟)
 */
unsigned char Get_Instant_Drip_Velocity(void)
{
    return Instant_Drip_Velocity;
}

/**
 * @brief 获取滴速状态
 * @return 状态码
 */
unsigned char Get_Drip_Status(void)
{
    return Drip_Status;
}

/**
 * @brief 获取总滴数
 * @return 总滴数
 */
unsigned long int Get_Drip_Count(void)
{
    return Drip_Num;
}

/**
 * @brief 获取剩余药量
 * @return 剩余药量
 */
float Dosage_Count(void)
{
    Dosage =  Dosage - 0.067;
    return Dosage;
}


/**
 * @brief 重置滴速计数器
 */
void Reset_Drip_Counter(void)
{
    Drip_Num = 0;
    Drip_Window_Num = 0;
    Time_Window_Start = uwtick;
    Time_Last_Drip = uwtick;
    Drip_Status = DRIP_STATUS_NORMAL;

    printf("滴速计数器已重置\r\n");
}
